#include "StdAfx.h"
#include "NetworkGraphics.h"


NetworkGraphics::NetworkGraphics(HDC hdc)
	: hdc(hdc)
{
	currDx = 0;
	currDy = 0;
	currentFactor = 1;
}

NetworkGraphics::~NetworkGraphics(void)
{
}

void NetworkGraphics::transform(LONG *x, LONG *y)
{	
	*x = (currentFactor * *x) + currDx;
	*y = (currentFactor * *y) + currDy;
}

void NetworkGraphics::loadRectPath(RECT rect)
{
	transform(&rect.left, &rect.top);
	transform(&rect.right, &rect.bottom);

	BeginPath(hdc);

	MoveToEx(hdc, rect.left, rect.top, NULL);

	LineTo(hdc, rect.left, rect.bottom);
	LineTo(hdc, rect.right, rect.bottom);
	LineTo(hdc, rect.right, rect.top);
	LineTo(hdc, rect.left, rect.top);

	EndPath(hdc);	
}

void NetworkGraphics::drawLine(int x1, int y1, int x2, int y2)
{
	transform((LONG *)&x1, (LONG *)&y1);
	transform((LONG *)&x2, (LONG *)&y2);

	SelectObject(hdc, GetStockObject(BLACK_PEN));

	BeginPath(hdc);

	MoveToEx(hdc, x1, y1, NULL);
	LineTo(hdc, x2, y2);	

	EndPath(hdc);	

	StrokePath(hdc);
}

void NetworkGraphics::drawRect(RECT rect)
{
	loadRectPath(rect);
	SelectObject(hdc, GetStockObject(BLACK_PEN));
	StrokePath(hdc);	
}

void NetworkGraphics::fillRect(RECT rect)
{
	loadRectPath(rect);
	SelectObject(hdc, GetStockObject(BLACK_BRUSH));
	StrokeAndFillPath(hdc);
}

POINT NetworkGraphics::getRectMiddle( RECT r )
{
	POINT p;

	p.x = (r.right - r.left) / 2 + r.left;
	p.y = (r.bottom - r.top) / 2 + r.top;

	return p;
}

void NetworkGraphics::scale(double factor)
{
	currentFactor += factor;
}

void NetworkGraphics::translate(int dx, int dy)
{
	currDx += dx;
	currDy += dy;
}

void NetworkGraphics::drawMachine(int x, int y, bool isBuisy)
{
	RECT rect;

	rect.left = x;
	rect.top = y;
	rect.right = x + MACHINE_SIZE;
	rect.bottom = y + MACHINE_SIZE;

	if(isBuisy)
	{
		fillRect(rect);
	}
	else
	{
		drawRect(rect);
	}
}

void NetworkGraphics::drawBuffer(int x, int y, int capacity, int count)
{
	RECT r = RECT();

	r.left = x;
	r.right = x + BUFFER_WIDTH;
	r.top = y;
	r.bottom = y + BUFFER_CELL_HEIGHT;
		 
	for(int i = 0; i < capacity; i++)
	{		
		if(i < capacity - count)
		{
			drawRect(r);
		}
		else
		{
			fillRect(r);
		}

		r.top += BUFFER_CELL_HEIGHT;
		r.bottom += BUFFER_CELL_HEIGHT;
	}
}

RECT NetworkGraphics::drawNest(int x, int y, int bufferCapacity, int bufferCount, int machinesCount, bool machinesBusiness [])
{
	RECT rect;

	rect.left = x;
	rect.top = y;
	rect.bottom = y + max(3 * NEST_INNER_PADDING + MACHINE_SIZE, 2 * NEST_INNER_PADDING + bufferCapacity * BUFFER_CELL_HEIGHT);
	rect.right = x + 2 * NEST_INNER_PADDING + BUFFER_WIDTH + machinesCount * (MACHINE_SIZE + NEST_INNER_PADDING) + 2 * NEST_INNER_PADDING;

	drawBuffer(rect.left + NEST_INNER_PADDING, rect.top + NEST_INNER_PADDING, bufferCapacity, bufferCount);

	for(int i = 0; i < machinesCount; i++)
	{
		drawMachine(
			rect.left + 2 * NEST_INNER_PADDING + BUFFER_WIDTH + 
			NEST_INNER_PADDING + i * (MACHINE_SIZE + NEST_INNER_PADDING), 
			rect.bottom - 2 * NEST_INNER_PADDING - MACHINE_SIZE, 
			machinesBusiness[i]);
	}

	drawLine(
		rect.left + 2 * NEST_INNER_PADDING + BUFFER_WIDTH,
		rect.bottom - 3 * NEST_INNER_PADDING - MACHINE_SIZE,
		rect.left + 2 * NEST_INNER_PADDING + BUFFER_WIDTH,
		rect.bottom - NEST_INNER_PADDING);

	drawLine(
		rect.left + 2 * NEST_INNER_PADDING + BUFFER_WIDTH,
		rect.bottom - NEST_INNER_PADDING,
		rect.right - NEST_INNER_PADDING, 
		rect.bottom - NEST_INNER_PADDING);

	drawLine(
		rect.right - NEST_INNER_PADDING, 
		rect.bottom - NEST_INNER_PADDING,
		rect.right - NEST_INNER_PADDING,
		rect.bottom - 3 * NEST_INNER_PADDING - MACHINE_SIZE);


	drawRect(rect);

	return rect;		
}

void NetworkGraphics::drawConnection(RECT firstNest, RECT secondNest)
{
	POINT middleFirst = getRectMiddle(firstNest);
	POINT middleSecond = getRectMiddle(secondNest);

	POINT p1, p2, p3, p4, p5, p6;

	p1.x = firstNest.right;
	p1.y = middleFirst.y;

	p2.x = p1.x + CONNECTION_MARGIN;
	p2.y = p1.y;

	p3.x = p2.x;
	p3.y = (firstNest.top - secondNest.top) / 2 + secondNest.top;

	p4.x = secondNest.left - CONNECTION_MARGIN;
	p4.y = p3.y;

	p5.x = p4.x;
	p5.y = middleSecond.y;

	p6.x = secondNest.left;
	p6.y = p5.y;

	if(p2.x > p5.x)
	{
		drawLine(p1.x, p1.y, p2.x, p2.y);
		drawLine(p2.x, p2.y, p3.x, p3.y);
		drawLine(p3.x, p3.y, p4.x, p4.y);
		drawLine(p4.x, p4.y, p5.x, p5.y);
		drawLine(p5.x, p5.y, p6.x, p6.y);
	}
	else
	{
		drawLine(p1.x, p1.y, p5.x, p2.y);
		drawLine(p5.x, p2.y, p5.x, p5.y);
		drawLine(p5.x, p5.y, p6.x, p6.y);
	}

}


